package com.sanley.piss.app.manager.shiro.jwt;

import com.gitee.dreamkaylee.jwt.token.SignedWithSecretKeyJwtRepository;
import com.gitee.dreamkaylee.shiro.authc.credential.CredentialsRetryLimitCredentialsMatcher;
import com.gitee.dreamkaylee.shiro.authz.repository.ShiroPrincipalRepository;
import com.gitee.dreamkaylee.shiro.boot.jwt.JwtPayloadRepository;
import com.gitee.dreamkaylee.shiro.boot.jwt.authc.JwtAuthenticationFailureHandler;
import com.gitee.dreamkaylee.shiro.boot.jwt.realm.JwtStatefulAuthorizingRealm;
import com.gitee.dreamkaylee.shiro.boot.jwt.realm.JwtStatelessAuthorizingRealm;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.authz.permission.RolePermissionResolver;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.realm.Realm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author limk
 * @date 2020/12/18 13:21
 */
@Configuration
public class ShiroJwtConfig {

    @Autowired(required = false)
    protected RolePermissionResolver rolePermissionResolver;
    @Autowired(required = false)
    protected PermissionResolver permissionResolver;

    @Bean
    public CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }

    @Bean
    public CredentialsRetryLimitCredentialsMatcher credentialsMatcher() {
        CredentialsRetryLimitCredentialsMatcher matcher = new CredentialsRetryLimitCredentialsMatcher();
        matcher.setCacheManager(cacheManager());
        matcher.setHashIterations(5);
        matcher.setHashAlgorithmName("MD5");
        return matcher;
    }

    @Bean
    @ConditionalOnMissingBean
    protected JwtAuthenticationFailureHandler jwtAuthenticationFailureHandler() {
        return new JwtAuthenticationFailureHandler();
    }

    @Bean
    public Realm jwtStatefulAuthorizingRealm(@Qualifier("sinopecRepository") ShiroPrincipalRepository sinopecRepository) {
        JwtStatefulAuthorizingRealm statefulAuthorizingRealm = new JwtStatefulAuthorizingRealm();
        statefulAuthorizingRealm.setCredentialsMatcher(credentialsMatcher());
        statefulAuthorizingRealm.setRepository(sinopecRepository);
        statefulAuthorizingRealm.setAuthenticationCachingEnabled(false);
        statefulAuthorizingRealm.setAuthorizationCachingEnabled(false);
        return statefulAuthorizingRealm;
    }

    @Bean
    public Realm jwtStatelessAuthorizingRealm(@Qualifier("jwtRepository") ShiroPrincipalRepository repository) {
        JwtStatelessAuthorizingRealm statelessAuthorizingRealm = new JwtStatelessAuthorizingRealm();
        statelessAuthorizingRealm.setRepository(repository);
        statelessAuthorizingRealm.setAuthenticationCachingEnabled(false);
        statelessAuthorizingRealm.setAuthorizationCachingEnabled(false);
        return statelessAuthorizingRealm;
    }

    @Bean
    @ConditionalOnMissingBean
    public SignedWithSecretKeyJwtRepository secretKeyJwtRepository() {
        return new SignedWithSecretKeyJwtRepository();
    }

    @Bean
    @ConditionalOnMissingBean
    public JwtPayloadRepository jwtPayloadRepository(SignedWithSecretKeyJwtRepository secretKeyJwtRepository) {
        return new SinopecJwtPayloadRepository(secretKeyJwtRepository);
    }

}
